package org.snail.employee.service.impl;

import com.dingtalk.open.client.api.model.corp.CorpUserDetail;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.NonNull;
import lombok.extern.log4j.Log4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.log4j.Logger;
import org.snail.attendence.bean.AliWorkDTO;
import org.snail.attendence.service.impl.AttendanceCheckServiceImpl;
import org.snail.common.ExcelUtils;
import org.snail.common.StringUtils2;
import org.snail.constant.EmpMsgConstant;
import org.snail.constant.ErrCodeConstant;
import org.snail.dept.bean.DepartDO;
import org.snail.department.service.impl.DepartmentTreeNodeService;
import org.snail.employee.bean.*;
import org.snail.employee.mapper.EmployeesMapper;
import org.snail.employee.service.EmployessService;
import org.snail.exception.BaseException;
import org.snail.exception.CommonException;
import org.snail.exception.EmpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

@Service
@Log4j
public class EmployeesServiceImpl implements EmployessService {

    private static final Logger LOGGER = Logger.getLogger(EmployeesServiceImpl.class);
    @Autowired
    private EmployeesMapper employeesMapper;
    @Autowired
    private AttendanceCheckServiceImpl attendanceCheckService;
    @Autowired
    private DepartmentTreeNodeService departmentTreeNodeService;
    @Autowired
    private EmployeeRedisService employeeRedisService;


    /**
     * 通过工号查询员工
     * @param aliWorkDTO
     * @return
     */
    private EmployeesDO findEmpByWorkNum(AliWorkDTO aliWorkDTO){
        EmployeesDO employeesDO = null;
        String workNum = aliWorkDTO.getWorkNum();
        EmpCondition empCondition = new EmpCondition();
        empCondition.setWorkNum(workNum);
        List<EmployeesDO> employeesDOs = employeesMapper.findAllEmp(empCondition);
        if(employeesDOs.size()==0){
            employeesDO = findEmpByName(aliWorkDTO);
        }else if(employeesDOs.size()>1){

        }else{
            employeesDO = employeesDOs.get(0);
        }
        return employeesDO;
    }

    /**
     * 通过姓名查询员工
     * @param aliWorkDTO
     * @return
     */
    private EmployeesDO findEmpByName(AliWorkDTO aliWorkDTO){
        EmployeesDO emp = null;
        EmpCondition empCondition = new EmpCondition();
        empCondition.setName(aliWorkDTO.getEmployeeName());
        List<EmployeesDO> allEmp = employeesMapper.findAllEmp(empCondition);
        if (null == allEmp || allEmp.isEmpty()) {
            LOGGER.error("=============根据姓名查不到该员工！姓名：" + aliWorkDTO.getEmployeeName());
        } else if (allEmp.size() == 1) {
            emp = allEmp.get(0);
        } else {
            LOGGER.error("=============存在员工重名的情况无法分辨！姓名：" + aliWorkDTO.getEmployeeName());
        }
        return emp;
    }



    /**
     * 更具state判断是新增员工还是删除员工
     *
     * @param employeesSaveEmpList
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws EmpException
     */
    public void saveEmpList_v2(EmployeesSaveEmpList employeesSaveEmpList) throws InvocationTargetException, IllegalAccessException, EmpException {
        List<EmployeesDO> empList = employeesSaveEmpList.getEmpList();
        String empType = employeesSaveEmpList.getEmpType();
        if (StringUtils.isBlank(empType)) {
            throw new EmpException(ErrCodeConstant.ERROR_CODE_NO_TYPE, "请选择excel文件类型");
        }
        for (EmployeesDO employeesDO : empList) {
            Integer state = employeesDO.getState();
            if (state == null) {
                throw new EmpException(ErrCodeConstant.ERROR_CODE_NO_STATE, "没有新增修改的标识(state)");
            }
            if (EmpMsgConstant.EXCEL_BASE.equals(empType)) {
                dealBaseEmp(state, employeesDO);
            } else if (EmpMsgConstant.EXCEL_PHONE.equals(empType)) {
                dealPhoneEmp(state, employeesDO);
            } else if (EmpMsgConstant.EXCEL_DETAIL.equals(empType)) {
                dealDetailEmp(state, employeesDO);
            }
        }
    }


    /*
        处理通讯录的更新和新增
     */
    private void dealPhoneEmp(Integer state, EmployeesDO employeesDO) throws InvocationTargetException, IllegalAccessException, EmpException {
        EmployeesPhoneDO employeesPhoneDO = new EmployeesPhoneDO();
        BeanUtils.copyProperties(employeesPhoneDO, employeesDO);
        employeesPhoneDO.setUpdateTime(new Date());
        String outNum = employeesPhoneDO.getOutNum();
        if (outNum != null) {
            if (outNum.contains("#N/A")) {
                employeesPhoneDO.setOutNum("");
            }
        }
        if (state.equals(EmpMsgConstant.EMP_STATE_SAVE)) {
            employeesMapper.saveVicePhoneEmployees(employeesPhoneDO);
            employeesMapper.saveMainPhoneEmployees(employeesPhoneDO);
            //修改缓存中的数据
//            EmpCondition empCondition = new EmpCondition();
//            empCondition.setWorkNum();
        } else if (state.equals(EmpMsgConstant.EMP_STATE_UPDATE)) {
            //更新主表
            EmpCondition empCondition = new EmpCondition();
            empCondition.setWorkNum(employeesPhoneDO.getWorkNum());
            Integer id = employeesMapper.findIdByWorkNum(empCondition);
            if (id == null) {
                throw new EmpException(ErrCodeConstant.ERROR_CODE_NO_EMP, "找不到此工号的员工");
            }
            employeesPhoneDO.setId(id);
            employeesMapper.updateMainPhoneEmployees(employeesPhoneDO);

            //更新副表
            empCondition.setEmpId(id);
            Integer viceId = employeesMapper.findViceIdById(empCondition);
            employeesPhoneDO.setViceId(viceId);
            employeesMapper.updateVicePhoneEmployees(employeesPhoneDO);
        }
    }

    /*
        处理基础表的跟新和新增
     */
    private void dealBaseEmp(Integer state, EmployeesDO employeesDO) throws InvocationTargetException, IllegalAccessException, EmpException {
        EmployeesBaseDO employeesBaseDO = new EmployeesBaseDO();
        BeanUtils.copyProperties(employeesBaseDO, employeesDO);
        if (state.equals(EmpMsgConstant.EMP_STATE_SAVE)) {
            employeesBaseDO.setCreateTime(new Date());
            employeesMapper.saveViceBaseEmployees(employeesBaseDO);
            employeesMapper.saveMainBaseEmployees(employeesBaseDO);
        } else if (state.equals(EmpMsgConstant.EMP_STATE_UPDATE)) {
            //更新主表
            EmpCondition empCondition = new EmpCondition();
            empCondition.setWorkNum(employeesBaseDO.getWorkNum());
            Integer id = employeesMapper.findIdByWorkNum(empCondition);
            if (id == null) {
                throw new EmpException(ErrCodeConstant.ERROR_CODE_NO_EMP, "找不到此工号的员工");
            }
            employeesBaseDO.setId(id);
            employeesBaseDO.setUpdateTime(new Date());
            employeesMapper.updateMainBaseEmployees(employeesBaseDO);
            //更新副表
            empCondition.setEmpId(id);
            Integer viceId = employeesMapper.findViceIdById(empCondition);
            employeesBaseDO.setViceId(viceId);
            employeesMapper.updateViceBaseEmployees(employeesBaseDO);
        }
    }

    private void dealDetailEmp(Integer state, EmployeesDO employeesDO) throws InvocationTargetException, IllegalAccessException, EmpException {
        EmployeesDetailDO employeesDetailDO = new EmployeesDetailDO();
        BeanUtils.copyProperties(employeesDetailDO, employeesDO);
        if (state.equals(EmpMsgConstant.EMP_STATE_SAVE)) {
            employeesMapper.saveViceDetailEmployees(employeesDetailDO);
            employeesMapper.saveMainDetailEmployees(employeesDetailDO);
        } else if (state.equals(EmpMsgConstant.EMP_STATE_UPDATE)) {
            //跟新主表
            EmpCondition empCondition = new EmpCondition();
            empCondition.setWorkNum(employeesDetailDO.getWorkNum());
            Integer id = employeesMapper.findIdByWorkNum(empCondition);
            if (id == null) {
                throw new EmpException(ErrCodeConstant.ERROR_CODE_NO_EMP, "找不到此工号的员工");
            }
            employeesDetailDO.setId(id);
            employeesMapper.updateMainDetailEmployees(employeesDetailDO);
            //跟新副表
            empCondition.setEmpId(id);
            Integer viceId = employeesMapper.findViceIdById(empCondition);
            employeesDetailDO.setViceId(viceId);
            employeesMapper.updateViceDetailEmployees(employeesDetailDO);
        }
    }


    /**
     * 改进预览功能
     * state 0不变
     * 1新增
     * 2修改
     *
     * @return
     */
    public List preview_v2(CommonsMultipartFile file, String empType, HttpServletRequest request) throws BaseException, InvocationTargetException, IllegalAccessException, ClassNotFoundException {
        //保存excel的部分字段<工号,员工信息>
        Map<String, EmployeesDO> excelMap = new HashMap<String, EmployeesDO>();
        //保存工号对应一个员工id<workNum,id>
        Map<String, Integer> workNumToIdMap = new HashMap<String, Integer>();
        //保存工号对应一个全部员工信息
        Map<String, EmployeesDO> AllFieldMap = new HashMap<String, EmployeesDO>();
        //文件路径
        String outfilePath = getOutFilePath(file, request);
        //  1. 解析excel转换成 Map<工号,部分字段的员工信息>
        parseExcelLessField(empType, excelMap, file, outfilePath);
        //  2. 根据工号查询id Map<工号,id>
        initWorkNumToIdMap(workNumToIdMap, excelMap);
        //初始化缓存
        saveId2empDOHCache();

        //  3. 从cach中根据id查询员工信息 做比较
        initWorkNumToAllField(AllFieldMap, workNumToIdMap);
        //  4.做比较设置状态新增,修改,增加
        List<EmployeesDO> empResult = compareList(excelMap, AllFieldMap, empType);

        List fileTypeList = getFileTypeList(empResult, empType);
        return fileTypeList;
    }

    //返回指定文件的bean
    private List<Object> getFileTypeList(List<EmployeesDO> empList, String empType) throws InvocationTargetException, IllegalAccessException {
        List<Object> fileList = new ArrayList<Object>();
        for (int i = 0; i < empList.size(); i++) {
            EmployeesDO employeesDO = empList.get(i);
            if (EmpMsgConstant.EXCEL_BASE.equals(empType)) {
                EmployeesBaseDO employeesPhoneDO = new EmployeesBaseDO();
                BeanUtils.copyProperties(employeesPhoneDO, employeesDO);
                fileList.add(employeesPhoneDO);
            } else if (EmpMsgConstant.EXCEL_PHONE.equals(empType)) {
                EmployeesPhoneDO employeesPhoneDO = new EmployeesPhoneDO();
                BeanUtils.copyProperties(employeesPhoneDO, employeesDO);
                fileList.add(employeesPhoneDO);
            } else if (EmpMsgConstant.EXCEL_DETAIL.equals(empType)) {
                EmployeesDetailDO employeesPhoneDO = new EmployeesDetailDO();
                BeanUtils.copyProperties(employeesPhoneDO, employeesDO);
                fileList.add(employeesPhoneDO);
            }
        }
        return fileList;
    }


    //获取文件路径;
    private String getOutFilePath(CommonsMultipartFile file, HttpServletRequest request) {
        String excelName = file.getOriginalFilename();
        String outfileName = "out" + excelName;
        String pathHome = request.getSession().getServletContext().getRealPath("upload");
        String outfilePath = pathHome + "/" + outfileName;
        return outfilePath;
    }

    private void parseExcelLessField(String empType, Map<String, EmployeesDO> excelMap, CommonsMultipartFile file, String outfilePath) throws IllegalAccessException, InvocationTargetException, EmpException {
        if (EmpMsgConstant.EXCEL_BASE.equals(empType)) {
            initExcelBaseMap(excelMap, file, outfilePath);
        } else if (EmpMsgConstant.EXCEL_PHONE.equals(empType)) {
            initExcelPhoneMap(excelMap, file, outfilePath);
        } else if (EmpMsgConstant.EXCEL_DETAIL.equals(empType)) {
            initExcelDetailMap(excelMap, file, outfilePath);
        }
    }

    //保存明细表相关字段
    private void initExcelDetailMap(Map<String, EmployeesDO> excelMap, CommonsMultipartFile file, String outfilePath) throws InvocationTargetException, IllegalAccessException {
        List<EmployeesDetailDO> employeesDetailDTOList = ExcelUtils.getListFromExcel(file, outfilePath, EmployeesDetailDO.class, 1);
        for (int i = 0; i < employeesDetailDTOList.size(); i++) {
            EmployeesDO employeesDO = new EmployeesDO();
            EmployeesDetailDO employeesDetailDO = employeesDetailDTOList.get(i);
            String workNum = employeesDetailDO.getWorkNum();
            if (StringUtils.isNotBlank(workNum)) {
                BeanUtils.copyProperties(employeesDO, employeesDetailDO);
                excelMap.put(workNum, employeesDO);
            }
        }
    }

    //保存通讯录表相关的字段
    private void initExcelPhoneMap(Map<String, EmployeesDO> excelMap, CommonsMultipartFile file, String outfilePath) throws EmpException, InvocationTargetException, IllegalAccessException {
        List<EmployeesPhoneDO> employeesPhoneDOList = ExcelUtils.getListFromExcel(file, outfilePath, EmployeesPhoneDO.class, 3);
        for (int i = 0; i < employeesPhoneDOList.size(); i++) {
            EmployeesDO employeesDO = new EmployeesDO();
            EmployeesPhoneDO employeesPhoneDO = employeesPhoneDOList.get(i);
            String workNum = employeesPhoneDO.getWorkNum();
            if (StringUtils.isNotBlank(workNum)) {
                BeanUtils.copyProperties(employeesDO, employeesPhoneDO);
                excelMap.put(workNum, employeesDO);
            }
        }
    }

    //保存基础表相关字段
    private void initExcelBaseMap(Map<String, EmployeesDO> excelMap, CommonsMultipartFile file, String outfilePath) throws InvocationTargetException, IllegalAccessException {
        List<EmployeesBaseDO> baseList = ExcelUtils.getListFromExcel(file, outfilePath, EmployeesBaseDO.class, 1);
        for (int i = 0; i < baseList.size(); i++) {
            EmployeesDO employeesDO = new EmployeesDO();
            EmployeesBaseDO employeesBaseDO = baseList.get(i);
            String workNum = employeesBaseDO.getWorkNum();
            if (StringUtils.isNotBlank(workNum)) {
                BeanUtils.copyProperties(employeesDO, employeesBaseDO);
                excelMap.put(workNum, employeesDO);
            }
        }
    }

    //保存一个工号对应一个id
    private void initWorkNumToIdMap(Map workNumToIdMap, Map excelPhoneMap) {
        Set<String> workNumSet = excelPhoneMap.keySet();
        for (String workNum : workNumSet) {
            EmpCondition condition = new EmpCondition();
            condition.setWorkNum(workNum);
            Integer id = employeesMapper.findIdByWorkNum(condition);
            workNumToIdMap.put(workNum, id);
        }
    }

    //通过id查询员工信息
    private void initWorkNumToAllField(Map workNumToAllField, Map workNumToIdMap) throws BaseException {
        Set<String> workNumSet = workNumToIdMap.keySet();
        for (String workNum : workNumSet) {
            EmpCondition empCondition = new EmpCondition();
            Integer id = (Integer) workNumToIdMap.get(workNum);
            empCondition.setEmpId(id);
            if (id != null) {
                EmployeesDO employeesDO = employeeRedisService.getEmpFromRedis(id + "");
                workNumToAllField.put(workNum, employeesDO);
            }

        }

    }

    //比较excel DO 和 数据库DO 设置状态
    private List<EmployeesDO> compareList(Map<String, EmployeesDO> excelMap, Map<String, EmployeesDO> allFieldMap, String empType) throws IllegalAccessException, InvocationTargetException, ClassNotFoundException {
        //不同的empType返回不同的结果
        boolean isSame = false;

        List<EmployeesDO> empList = new ArrayList<>();              //普通的人员list
        List<EmployeesDO> empListForUpdate = new ArrayList<>();     //添加修改人员的list
        List<EmployeesDO> empListForNew = new ArrayList<>();        //新增人员List
        Set<String> workNumSet = excelMap.keySet();
        for (String workNum : workNumSet) {
            Boolean hasKey = allFieldMap.containsKey(workNum);
            EmployeesDO employeesDO = excelMap.get(workNum);
            //新增的员工
            if (!hasKey) {
                employeesDO.setState(EmpMsgConstant.EMP_STATE_SAVE);
                empListForNew.add(employeesDO);
                continue;
            }
            //比较是否相等
            if (EmpMsgConstant.EXCEL_PHONE.equals(empType)) {
                isSame = comparePhone(excelMap.get(workNum), allFieldMap.get(workNum));
            } else if (EmpMsgConstant.EXCEL_BASE.equals(empType)) {
//                isSame = compareBean(excelMap.get(workNum), allFieldMap.get(workNum));
            } else if (EmpMsgConstant.EXCEL_DETAIL.equals(empType)) {
//                isSame = compareBean(excelMap.get(workNum), allFieldMap.get(workNum));
            }

            if (isSame) {
                employeesDO.setState(EmpMsgConstant.EMP_STATE_SAME);
                empList.add(employeesDO);
            } else {
                employeesDO.setState(EmpMsgConstant.EMP_STATE_UPDATE);
                empListForUpdate.add(employeesDO);
            }

        }
        empList.addAll(0, empListForUpdate);  //其次
        empList.addAll(0, empListForNew);    //排在最前面
        return empList;
    }


    /**
     * 通过工号查找员工id
     *
     * @param empCondition
     * @return
     */
    public Integer findIdByWorkNum(EmpCondition empCondition) {
        Integer id = employeesMapper.findIdByWorkNum(empCondition);
        return id;
    }

    /**
     * 删除员工
     *
     * @param idList
     */
    public void deleteEmpList(List<Integer> idList) throws CommonException {
        for (int i = 0; i < idList.size(); i++) {
            deleteEmp(idList.get(i));
            //删除员工考勤表历史记录
//            attendanceCheckService.deleteAttHistoryByEmpId(idList.get(i));
        }
    }


    /**
     * 删除员工
     *
     * @param idList
     */
    public void deleteMainEmpListByDingId(List<String> idList) {
        for (int i = 0; i < idList.size(); i++) {
            employeesMapper.deleteMainEmpByDingId(idList.get(i));
        }
    }

    /**
     * 通过工号做假删除
     *
     * @param id
     */
    public void deleteEmp(Integer id) {
        //删除副表中的数据
        EmpCondition empCondition = new EmpCondition();
        empCondition.setEmpId(id);
        Integer viceId = employeesMapper.findViceIdById(empCondition);
        employeesMapper.deleteViceEmp(viceId);
        //删除主表中的数据
        employeesMapper.deleteMainEmp(id);
    }

    /**
     * 存id_empDO，数据结构为Hash 到redis中,这个应该算是初始化缓存
     */
    public Integer saveId2empDOHCache() throws BaseException {
        Integer resultCode = 0;
        EmpCondition empCondition = new EmpCondition();
        empCondition.setIsDel(0);
        List<EmployeesDO> allEmp = employeesMapper.findAllEmp(empCondition);
        if (allEmp.isEmpty()) {
            LOGGER.error("查询不到所有员工的信息");
        } else {
            for (EmployeesDO employeesDO : allEmp) {
                if (employeesDO.getEmpId() == null || employeesDO.getEmpId() == 0) {
                    throw new CommonException(ErrCodeConstant.ILLEGAL_PARAM, "人事基本信息表不能为空！");
                }
                resultCode = employeeRedisService.saveOrUpdateEmpToRedis(employeesDO);
            }
        }
        return resultCode;
    }

    public EmployeesDO getEmpDOFromHCache(Object hashKey) throws BaseException {
        if (StringUtils2.objIsNull(hashKey)) {
            throw new CommonException(ErrCodeConstant.ILLEGAL_PARAM, "获取key时参数不能为空！");
        }
        EmployeesDO employeesDO = employeeRedisService.getEmpFromRedis(hashKey.toString());
        return employeesDO;

    }

    /**
     * 两个对象作比较
     *
     * @param obj
     * @param obj2
     * @return
     * @throws ClassNotFoundException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private Boolean comparePhone(EmployeesDO obj, EmployeesDO obj2) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException {
        EmployeesPhoneDO employeesPhoneDO = new EmployeesPhoneDO();
        EmployeesPhoneDO employeesPhoneDO1 = new EmployeesPhoneDO();
        BeanUtils.copyProperties(employeesPhoneDO, obj);
        BeanUtils.copyProperties(employeesPhoneDO1, obj2);
        Boolean compare = employeesPhoneDO.equals(employeesPhoneDO1);
        return compare;
    }

    /**
     * 将层级员工信息封装成map
     *
     * @param deptId
     * @return
     */
    public Map<Integer, List<EmployeesDO>> getEmployeeByDeptMap(Long deptId) {

        Set<DepartDO> treeMenuSet = departmentTreeNodeService.getTreeNodeList(deptId);
        Iterator<DepartDO> iterator = treeMenuSet.iterator();
        List<EmployeesDO> employeesDOS = null;
        Map<Integer, List<EmployeesDO>> deptMap = new HashMap<>();
        while (iterator.hasNext()) {
            EmpCondition empCondition = new EmpCondition();
            DepartDO departDO = iterator.next();
            empCondition.setDeptId(Integer.parseInt(departDO.getId().toString()));
            employeesDOS = employeesMapper.findEmpListByEmpCondition(empCondition);
            deptMap.put(Integer.parseInt(departDO.getId().toString()), employeesDOS);
        }
        return deptMap;
    }

    /**
     * 根据工号找到对应的员工Id
     *
     * @param empWorkNo
     * @return
     */
    public Integer getEmpIdByWorkNo(String empWorkNo) {
        List<Map<Object, Object>> empIdByWorkNoMap = employeesMapper.findEmpIdByWorkNoMap();
        HashMap<String, Integer> empIdAndWorkNoMap = new HashMap<>();
        if (empIdByWorkNoMap.size() > 0) {
            for (Map<Object, Object> empIdAndWorkNo : empIdByWorkNoMap) {
                Integer empId = (Integer) empIdAndWorkNo.get("empId");
                String workNo = (String) empIdAndWorkNo.get("workNum");
                empIdAndWorkNoMap.put(workNo, empId);
            }
        }
        Integer employeeId = empIdAndWorkNoMap.get(empWorkNo);
        return employeeId;
    }

    /**
     * 根据员工id修改员工数据
     *
     * @param employeesDO
     */
    public void updateEmp(EmployeesDO employeesDO) throws BaseException {
        employeesMapper.updateMainEmployees(employeesDO);
        employeesMapper.updateViceEmployees(employeesDO);
        employeeRedisService.saveOrUpdateEmpToRedis(employeesDO);
    }

    //===================================================新增或者使用的方法=============================================================
    /**
     * 通过DingId查找员工
     *
     * @param empCondition
     * @return
     */
    public EmployeesDO findEmpByDingId(EmpCondition empCondition) throws EmpException {
        if (empCondition.getDingId() == null) {
            throw new EmpException(ErrCodeConstant.ERROR_CODE_NO_EMPID, "没有员工DingId");
        }
        EmployeesDO employeesDO = employeesMapper.findEmpByDingId(empCondition);
        return employeesDO;
    }

    /**
     * 从钉钉获取数据创建人员信息
     *
     * @param employeesDO4Ding
     */
    public void InsertEmpFromDingding(EmployeesDO employeesDO4Ding) {
        employeesDO4Ding.setIsDel(0);
        employeesMapper.InsertEmpFromDingding(employeesDO4Ding);
        //从新从数据库获取数据后刷新缓存
        putEmployeesDO2Redis(employeesDO4Ding);
    }

    /**
     * 从钉钉获取数据更新人员信息
     *
     * @param employeesDO
     */
    public void updateEmpFromDingding(EmployeesDO employeesDO) {
        employeesMapper.updateMainEmployees(employeesDO);
        //从新从数据库获取数据后刷新缓存
        putEmployeesDO2Redis(employeesDO);
    }

    /**
     * 根据钉钉UserID获取数据库员工信息
     * @param dingID
     * @return
     */
    public EmployeesDO findEmpByDingId(String dingID) {
        EmployeesDO employeesDO = null;
        try {
            EmpCondition empCondition = new EmpCondition();
            empCondition.setDingId(dingID);
            empCondition.setIsDel(0);
            employeesDO = findEmpByDingId(empCondition);
        } catch (EmpException e) {
            log.error("根据DingID获取员工报错", e);
        }
        return employeesDO;
    }


    /**
     * 从新从数据库获取数据后刷新缓存
     * @param employeesDO
     */
    private void putEmployeesDO2Redis(EmployeesDO employeesDO) {
        //从新从数据库获取数据后刷新缓存
        try {
            if(null!=employeesDO) {
                log.info("employeesDO.getDingId(): " + employeesDO.getDingId());
                EmployeesDO employeesDODB  = findEmpByDingId(employeesDO.getDingId());
                log.info("employeesDODB: " + employeesDODB);
                if(null!=employeesDODB) {
                    employeeRedisService.saveOrUpdateEmpToRedis(employeesDODB);
                }
            }
        } catch (BaseException e) {
            log.error("从新获取数据到Redis失败", e);
        }
    }

    /**
     * 查询所有员工信息
     * 包含分页查询
     *
     * @return
     */
    public Map<String, PageInfo> findAllEmp(EmpCondition empCondition) {
        String workNum = empCondition.getWorkNum();
        if(StringUtils.isNotBlank(workNum)&&workNum.equals(empCondition.getName())){
            empCondition.setWorkNum("");
        }
        Integer startPage = empCondition.getStartPage();
        Integer pageSize = empCondition.getPageSize();
        if (startPage != null && pageSize != null) {
            PageHelper.startPage(startPage, pageSize);
        }
        List<EmployeesDO> list = employeesMapper.findAllEmp(empCondition);
        if(list.size()==0){
            startPage = EmpMsgConstant.START_PAGE;
            pageSize  = EmpMsgConstant.PAGE_SIZE;
            PageHelper.startPage(startPage,pageSize);
            list = employeesMapper.findAllEmp(empCondition);
        }
        //使用PageInfo包装查询结果，只需要将pageInfo交给页面就可以
        PageInfo pageInfo = new PageInfo<>(list);
        //pageINfo封装了分页的详细信息，也可以指定连续显示的页数
        Map<String, PageInfo> map = new HashMap<String, PageInfo>();
        map.put("pageInfo", pageInfo);
        return map;
    }

    /**
     * 根据阿里工号、工号、名字中的一个获取对象
     * @param aliNum
     * @param num
     * @param name
     * @return
     */
    public EmployeesDO findEmpByNumOrName(String aliNum, String num, String name) {
        if(null==aliNum && null==num && null==name) {
            log.error("阿里工号、工号、名字中必须有一个不为空");
        } else {

        }
        EmployeesDO emp = null;
        if (!StringUtils2.isNull(aliNum) && !"null".equals(aliNum)) {   //根据阿里工号找
            try {
                emp = employeesMapper.findEmpByOutNum(aliNum);
            } catch (Exception e) {
                LOGGER.error("外包工号为:" + aliNum + "根据外包工号查询人员失败！", e);
            }
        }

        if(!StringUtils2.isNull(num) && !"null".equals(num) && null==emp) { //根据工号查找
            try {
                emp = employeesMapper.findEmpByWorkNum(num);
            } catch (Exception e) {
                LOGGER.error("工号为:" + num + "根据工号查询人员失败！", e);
            }
        }

        if(!StringUtils2.isNull(name) && !"null".equals(name) && null==emp && StringUtils2.isNull(num) && StringUtils2.isNull(aliNum)){    //根据姓名查找
            EmpCondition empCondition = new EmpCondition();
            empCondition.setName(name);
            List<EmployeesDO> allEmp = employeesMapper.findAllEmp(empCondition);
            if (null==allEmp || allEmp.isEmpty()) {
                LOGGER.error("=============根据姓名查不到该员工！姓名：" + name);
            } else if(allEmp.size() == 1) {
                emp = allEmp.get(0);
            } else {
                LOGGER.error("=============存在员工重名的情况无法分辨！姓名：" + name);
            }
        }

        return emp;
    }

    /**
     * 对比钉钉和数据数据是否变化
     * @param employeesDO4DB
     * @param employeesDO4Ding
     * @return
     */
    public boolean compareEmpDBAndDing(EmployeesDO employeesDO4DB, EmployeesDO employeesDO4Ding) {
        boolean flag = false;
        if(null!=employeesDO4Ding && null!=employeesDO4DB) {
            if( (null!=employeesDO4Ding.getOutNum() && !employeesDO4Ding.getOutNum().equals(employeesDO4DB.getOutNum())) ||
                    (null!=employeesDO4Ding.getPhone() && !employeesDO4Ding.getPhone().equals(employeesDO4DB.getPhone())) ||
                    (null!=employeesDO4Ding.getName() && !employeesDO4Ding.getName().equals(employeesDO4DB.getName())) ||
                    (null!=employeesDO4Ding.getEmail() && !employeesDO4Ding.getEmail().equals(employeesDO4DB.getEmail())) ||
                    (null!=employeesDO4Ding.getWorkNum() && !employeesDO4Ding.getWorkNum().equals(employeesDO4DB.getWorkNum())) ) {
                //复制DB ID到钉钉Bean对象
                if(null!=employeesDO4DB.getEmpId()) {
                    employeesDO4Ding.setEmpId(employeesDO4DB.getEmpId());
                    flag = true;
                }
            }
        }
        return flag;
    }

    /**
     * 通过id查找员工
     *
     * @param empCondition
     * @return
     */
    public EmployeesDO findEmpById(EmpCondition empCondition) throws EmpException {
        if (empCondition.getEmpId() == null) {
            throw new EmpException(ErrCodeConstant.ERROR_CODE_NO_EMPID, "没有员工id");
        }
        EmployeesDO employeesDO = employeesMapper.findEmpById(empCondition);
        return employeesDO;
    }


    /**
     * 根据条件查找员工信息
     * @param empCondition
     * @return
     */
    public Map<String, Object> findEmpByEmpCondition(EmpCondition empCondition) {

        Integer startPage = empCondition.getStartPage();
        Integer pageSize = empCondition.getPageSize();
        if (startPage != null && pageSize != null) {
            PageHelper.startPage(startPage, pageSize);
        }
        List<EmployeesDO> empList = employeesMapper.findEmpListByEmpCondition(empCondition);
        PageInfo pageInfo = new PageInfo(empList);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("pageInfo", pageInfo);
        return map;
    }

    /**
     * 将CorpUserDetail对象的List放到缓存中
     * @param deptUserList
     * @return
     */
    @Override
    public boolean pushEmpToRedis(List<CorpUserDetail> deptUserList) {
        boolean result = true;
        if (null == deptUserList) {
            log.info("======================部门人员存入redis中，列表为空！");
            result = false;
        } else {
            for (CorpUserDetail corpUserDetail : deptUserList) {
                if (null == corpUserDetail || org.springframework.util.StringUtils.isEmpty(corpUserDetail.getJobnumber())) {
                    log.error(" ======================员工没有找到外包工号！员工姓名：" + corpUserDetail.getName());
                } else {
                    try {
                        employeeRedisService.saveOrUpdateDingDingEmpToRedis(corpUserDetail.getJobnumber(), corpUserDetail);//将人员存入redis
                    } catch (BaseException e) {
                        LOGGER.error("保存到Reids失败" + corpUserDetail.getJobnumber() , e);
                    }
                }
            }
        }

        return result;
    }

    /**
     * 转换钉钉对象为EmployeesDO
     * @param corpUserDetail
     * @return
     */
    public EmployeesDO transCorpUserDetail2EmployeesDO(CorpUserDetail corpUserDetail) {
        EmployeesDO employeesDO = null;
        if(null!=corpUserDetail) {
            employeesDO = new EmployeesDO();
            employeesDO.setDingId(corpUserDetail.getUserid());
            employeesDO.setName(corpUserDetail.getName());
            employeesDO.setEmail(corpUserDetail.getEmail());
            employeesDO.setPhone(corpUserDetail.getMobile());
            employeesDO.setWorkNum(corpUserDetail.getJobnumber());

            Map<String, String> extAttrMap = corpUserDetail.getExtattr();
            log.info("name: " + corpUserDetail.getName() + ", extAttrMap: " + extAttrMap);
            if(null!=extAttrMap) {
                String outNum = extAttrMap.get(EmpMsgConstant.OUTNUM_KEY);
                if(null!=outNum) {
                    employeesDO.setOutNum(outNum);
                }
            }
            employeesDO.setIsDel(0);
        }
        return employeesDO;
    }
}